﻿"""This is a postgre database manipulator"""

from mydb.basic import base as superbase
from mydb.basic import relations as superrelations
from mydb.basic import view as superview
from mydb.basic import table as supertable
from mydb.basic import aview as superaview
from mydb.basic import atable as superatable
import postgresql.driver as pg_driver

from itertools import islice


class base(superbase):
	"This class is a base connector"
	#print (self.__doc__)
	#beginning of class suite
	def __init__(self):
		super(base, self).__init__()
		self.driver=pg_driver
		self.user='palo'
		self.passwd='palo'
		self.host='sa-serv8'
		self.port=5432
		self.base='test_so'
		self.variable='$'
	
	def open(self):
		"This function opens connection to base"
		#print (self.open.__doc__)
		#beginning of function suite
		self.conn = self.driver.connect(user = self.user, password = self.passwd, host = self.host, port = self.port, database = self.base)
		return

	def execute_in_cycle(self, string, row=None):
		"This function executes statement against the base optional for a row of values"
		#beginning of function suite
		if not row:
			result=self.conn.prepare(string).rows()
		else:
			result=self.conn.prepare(string).rows(row)
		#end of function suite
		return result

	def execute_many_in_cycle(self, string, rows):
		"This function executes a statement for rows of values"
		#beginning of function suite
		#Переменной result присваивается результат выполнения запроса:
		result=self.conn.prepare(string).load_rows(rows)
		#end of function suite
		return result

	def commit_in_cycle(self, string):
		"This function executes statement against the base and commits it"
		#beginning of function suite
		self.conn.execute(string)
		#end of function suite
		return

	def execute(self, string, row=None, lim=0):
		"This function connects to base and executes a statement optional for a row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			if lim==0:
				result=self.conn.prepare(string)()
			else:
				result=list(islice(self.conn.prepare(string).rows(),0,lim))
		else:
			if lim==0:
				result=self.conn.prepare(string)(row)
			else:
				result=list(islice(self.conn.prepare(string).rows(row),0,lim))
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		return result

	def generate(self, string, row=None, lim=1000):
		"This function has to be done"
		return []
		
	def iterate(self, string, row=None, start=None, stop=None, step=None):
		"This function connects to base and executes a statement optional for a row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			result=islice(self.conn.prepare(string).rows(), start, stop, step)
		else:
			result=islice(self.conn.prepare(string).rows(row), start, stop, step)
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		#Функция возвращает итератор результатов запроса
		return result
	
	def execute_many(self, string, rows):
		"This function connects to base and executes a statement for rows of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Переменной result присваивается результат выполнения запроса:
		result=self.conn.prepare(string).load_rows(rows)
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		return result

	def commit(self, string):
		"This function connects to base, executes a statement and commits it"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		self.conn.execute(string)
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		return

	#end of class base suite

class relations(superrelations):
	"This class counts and select records for relations"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(relations, self).__init__()
		self.base=base()
#		self.variable='$1'
	#Заменяется родительская функция
	def catalogue(self, type):
		return 'pg_'+type.upper()
	
	#Заменяется родительская функция
	def field(self, type):
		return type.lower()[:-1]+'name'
	
	#Заменяется родительская функция
	def type(self,type):
		'Function returns base specific type sign'
		dict={'t':'tables','v':'views'}
		return dict[type]

	#end of class relations suite

class view(superview):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		self.base=base()
		self.relations=relations()
		self.relations.base=self.base
		self.case=False

	def SqlCreate(self, name, fields, query, param):
		"Function returns sql string for the view create query"
		return "CREATE "+param+" VIEW "+self.SqlCase(name)+" AS "+query

	#end of class view suite

class table(supertable):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(table, self).__init__()
		self.base=base()
		self.relations=relations()
		self.relations.base=self.base
		self.case=False
		self.seq_postfix='_id_seq'
		self.constraint_postfix='_pkey'

	def seq_create_extra(self, name, primary):
		return ';'+self.newline+'ALTER TABLE'+' '+self.SqlCase(name+self.seq_postfix)+' '+'OWNER TO openerp'

	def tab_create_extra(self, name, comment):
		return ';'+self.newline+'ALTER TABLE'+' '+self.SqlCase(name)+' '+'OWNER TO openerp'+';'+self.newline+'COMMENT ON TABLE'+' '+self.SqlCase(name)+' '+'IS'+' '+"'"+comment+"'"

	def seq_drop_extra(self):
		return ' '+'CASCADE'

	#def SqlCreateTab(self, param, name, fields, primary, comment):
	#	"Function returns sql string for the view create query"
	#	result='CREATE'+' '+param+' '+'TABLE'+' '+self.SqlCase(name)+' '+self.newline
	#	result+='('+self.newline
	#	for row in fields:
	#		result+=self.SqlCase(row[0])+' '+self.SqlCase(row[1])+' '+self.SqlCase(row[2])+',-- '+str(row[3])+self.newline
	#	if primary!='':
	#		result+='CONSTRAINT'+' '+self.SqlCase(name)+self.constraint_postfix+' '+'PRIMARY KEY ('+self.SqlCase(primary)+')'
	#	result+=self.newline+')'
	#	result+=self.tab_create_extra(name, comment)
	#	return result

	def SqlVariables(self, list):
		"Function returns base specific list of variables"
		result=''
		for x in range(len(list)):
			result+=self.base.variable+str(x+1)+', '
		return '('+result[:-2]+')'

	def delete(self, name, clause=[]):
		'Function deletes records where clause is satisfied'
		#print (self.delete.__doc__)
		#beginning of function suite
		#Переменной result присваивается результат запроса
		#end of function suite
		return self.base.execute('DELETE'+' '+'FROM'+' '+self.SqlCase(name)+self.SqlClause(clause))[1]

	def update(self, name, dict, clause=[]):
		'Function updates columns where clause is satisfied'
		#print (self.update.__doc__)
		#beginning of function suite
		#Переменной result присваивается результат запроса
		#end of function suite
		return self.base.execute('UPDATE'+' '+self.SqlCase(name)+' '+'SET'+' '+self.SqlColumnValue(dict)+' '+self.SqlClause(clause))[1]

	#end of class table suite

class aview(superaview):
	"This class is a manipulater for a view"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(aview, self).__init__()
		self.view=view()

	#end of class aview suite

class atable(superatable):
	"This class is a manipulator for a table"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(atable, self).__init__()
		self.table=table()

	#end of class atable suite

#Вывод ошибок возвращается "в исходное положение"

#sys.stderr.close()
#sys.stderr = sys.__stderr__